home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / DCLAP 4j / DClap / DApplication.cpp < prev    next >
Encoding:
Text File  |  1995-12-17  |  26.6 KB  |  1,138 lines  |  [TEXT/R*ch]

  1. // DApplication.cp
  2.  
  3.  
  4. #include "DClap.h"
  5. #include "DFindDlog.h"
  6.  
  7.  
  8. #if 0
  9. // Skeleton for application is
  10.  
  11. extern "C" Int2 Main (void)
  12. {
  13.   DMyApplication* myapp = new DMyApplication();
  14.   myapp->IApplication("App Name");
  15.   myapp->Run();
  16.   return 0;
  17. }
  18.  
  19. #endif
  20.  
  21.  
  22. DApplication* gApplication = NULL;        // the current application object
  23.  
  24. char* DApplication::kName=  NULL;
  25. char* DApplication::kVersion= NULL;
  26. char* DApplication::kHelpfolder = "Help";
  27.  
  28.  
  29.                     
  30. class DNoteWindow : public DWindow 
  31. {
  32. public:    
  33.     DNoteWindow(const char* message) :
  34.         DWindow( 0, NULL, DWindow::fixed, -5, -5, -50, -20, NULL)
  35.     {    
  36.     DNotePanel* note= new DNotePanel(0, this, message, 0, 0, Nlm_systemFont, justcenter);
  37.     }
  38.  
  39. };
  40.  
  41.  
  42.  
  43.  
  44.  
  45. class DWindowChoiceDialog : public DWindow 
  46. {
  47. public:
  48.     DListBox * fListBox;
  49.     short             fChoice;
  50.     DList      * fList;
  51.     
  52.     DWindowChoiceDialog();
  53.     void Open();
  54.     void OkayAction();
  55.     DWindow* Result();
  56. };
  57.  
  58.  
  59. DWindowChoiceDialog::DWindowChoiceDialog() :
  60.         DWindow( 0, NULL, DWindow::fixed, -10, -10, -50, -20, "Window list", kDontFreeOnClose),
  61.         fChoice(-1),
  62.         fList(NULL),
  63.         fListBox(NULL)
  64. {    
  65.     fList= gWindowManager->GetWindowList();
  66. }
  67.  
  68. void DWindowChoiceDialog::Open()
  69. {
  70.         // NOTE: this window is in window list !!
  71.     DPrompt* pr= new DPrompt(0, this, "Select a window");         
  72.     DListBox* lb= new DListBox(0, this, 20, 5, false);
  73.     fListBox= lb;
  74.     lb->SetResize( DView::relsuper, DView::relsuper);
  75.     lb->StartAppending();
  76.             
  77.     if (fList) {
  78.         char    title[256];
  79.         long i, n= fList->GetSize();
  80.         for (i= n-1; i>=0; i--) {
  81.             DWindow* win= (DWindow*) fList->At(i);
  82.             if (win != this) 
  83.             {
  84.                 win->GetTitle(title,256);
  85.                 lb->Append( title);
  86.                 }
  87.             }
  88.          }
  89.     lb->DoneAppending();
  90.     lb->SetValue(1); // doesn't seem active on DListBox display
  91.     
  92.     this->AddOkayCancelButtons();    
  93.     DWindow::Open();
  94. }
  95.  
  96. void DWindowChoiceDialog::OkayAction() 
  97.     //fChoice= fListBox->GetValue() - 1;  
  98.         //min GetValue==1, win fChoices == 0..GetSize-2, skip topwin = this
  99.     fChoice= (fList->GetSize() - 1) - (fListBox->GetValue() - 1);   
  100. }
  101.     
  102. DWindow* DWindowChoiceDialog::Result() 
  103.     if (fChoice<0) return NULL;
  104.     else return (DWindow*) fList->At(fChoice); 
  105. }
  106.     
  107.  
  108.  
  109.  
  110.  
  111. // CLASS DApplication
  112.  
  113. DApplication::DApplication() :
  114.     DTaskMaster(cAppl)
  115. {
  116.     fDone= false;        
  117.     fAppWindow= NULL;  
  118.     fPathname= NULL;
  119.     fShortname= NULL;
  120.     fAboutLine= NULL;
  121.     fFileSuffix= NULL;
  122.     fAcceptableFileTypes= NULL;
  123.     gApplication= this;
  124.         // default file types
  125.     fFileSuffix = ".txt";
  126.     fAcceptableFileTypes= "TEXT";
  127. }
  128.  
  129.  
  130.  
  131. void DApplication::IApplication(const char* theAppName)
  132. {
  133.     //xdebug("DApplication::IApplication");
  134.     DClapGlobals* initglobals = new DClapGlobals();
  135.     gCursor->watch();  
  136.  
  137.     fPathname = StrDup( gFileManager->GetProgramPath());
  138.     if (theAppName) 
  139.         fShortname= StrDup( theAppName);
  140.     else if (kName) 
  141.         fShortname= StrDup( kName);
  142.     else {
  143.         fShortname= StrDup( gFileManager->FilenameFromPath(fPathname));   
  144.         char * suf= (char*)gFileManager->FileSuffix(fShortname);
  145.         if (suf) *suf= 0; // we don't want no steenking suffix here
  146.         }
  147.         
  148.     char buf[512];
  149.     sprintf( buf, "About %s...", Shortname()); 
  150.     fAboutLine= StrDup(buf);
  151.  
  152. #ifndef WIN_MAC
  153.     if (!fAppWindow) {
  154.             // Non-Mac apps need an fAppWindow to put any application menus into 
  155.             // eventually want user pref for main wind rect...
  156.         fAppWindow= new DWindow(cAppW, this, DWindow::document, 450, 60, 2, 2, (char*)Shortname());
  157.         gWindowManager->SetAppWindow(fAppWindow);
  158.         //fAppWindow->Open(); //<<bad here -- main event loop
  159.         }
  160. #endif
  161.     
  162.     if (!gIconList) gIconList = new DIconList(); //<< do in DIconList.cpp as global init.
  163.   gIconList->ReadAppIcons();
  164.  
  165.     this->InitSpecialEvents();
  166.     this->InstallDefaultPrefs(); // do before calling any GetPref, after ShortName set
  167.     DFindDialog::InitFindDialog();
  168.     
  169.         // read some user prefs
  170.     gTextFontName= this->GetPref( "gTextFontName", "fonts", gTextFontName);
  171.     gTextFontSize= this->GetPrefVal( "gTextFontSize", "fonts", "12");
  172.     gTextTabStops= this->GetPrefVal( "gTextTabStops", "fonts", "4");
  173.     gTextFont         = Nlm_GetFont( gTextFontName, gTextFontSize, false, false, false, NULL);
  174.     if (!gTextFont) gTextFont= Nlm_programFont;
  175.  
  176.     DCluster::SetFont(Nlm_programFont);  
  177.  
  178.     this->SetUpMenus();
  179.     this->UpdateMenus(); // !! need to have this called in task loop somewhere !!
  180.  
  181.  
  182. DApplication::~DApplication()
  183. {
  184.     if (gIconList) gIconList->suicide();
  185.     if (fAboutLine) MemFree( fAboutLine);
  186.     if (fShortname) MemFree( fShortname);
  187.     if (fPathname) MemFree( fPathname);
  188.     gApplication= NULL;
  189. }  
  190.  
  191.  
  192.  
  193. const char*    DApplication::Pathname(void)
  194. {
  195.     return    fPathname;
  196. }
  197.  
  198. const char*    DApplication::Shortname(void)
  199. {
  200.     static char buf[256];
  201.     StrNCpy(buf, fShortname, 256); // having problems w/ someone mangling this string !
  202.     return buf;
  203. }
  204.  
  205.  
  206.  
  207.  
  208. #ifdef WIN_MAC
  209. #ifndef __APPLEEVENTS__
  210.     // undef some conflicts b/n Types.h && NlmTypes
  211. #undef Handle
  212. #undef true
  213. #undef false
  214. //#undef Boolean
  215. #include <AppleEvents.h>
  216. //#define Boolean  Nlm_Boolean
  217. #endif
  218.  
  219. // ??!? 68k mac calls to here now fail --  
  220. // !! REQUIRES 'pascal' function call settings for Mac68K callbacks !
  221.  
  222. #define CALLBACKFORM pascal
  223. //#define CALLBACKFORM extern "C"
  224. //#define CALLBACKFORM static
  225.  
  226. #endif
  227.  
  228. #ifdef WIN_MOTIF
  229. #include <signal.h>
  230. #if defined(OS_UNIX_SUN) || defined(OS_UNIX_IRIX)
  231. #include <sys/wait.h>
  232. #else
  233. #include <wait.h>
  234. #endif
  235. #endif
  236.  
  237.  
  238. // === AppleEvent Numbers ===
  239.  
  240. enum {
  241.                                         // Required Suite
  242. ae_OpenApp            = 1001,
  243. ae_OpenDoc            = 1002,
  244. ae_PrintDoc            = 1003,
  245. ae_Quit                = 1004,
  246.  
  247.                                         // Core Suite
  248. ae_Clone            = 2001,
  249. ae_Close            = 2002,
  250. ae_CountElements    = 2003,
  251. ae_CreateElement    = 2004,
  252. ae_Delete            = 2005,
  253. ae_DoObjectsExist    = 2006,
  254. ae_GetClassInfo        = 2007,
  255. ae_GetData            = 2008,
  256. ae_GetDataSize        = 2009,
  257. ae_GetEventInfo        = 2010,
  258. ae_Move                = 2011,
  259. ae_Open                = 1002,        // Same as ae_OpenDoc
  260. ae_Print            = 1003,        // Same as ae_PrintDoc
  261. ae_Save                = 2012,
  262. ae_SetData            = 2013,
  263.                                         // Miscellaneous Standards
  264. ae_ApplicationDied    = 3001,
  265. ae_BeginTransaction    = 3002,
  266. ae_Copy                = 3003,
  267. ae_CreatePublisher    = 3004,
  268. ae_Cut                = 3005,
  269. ae_DoScript            = 3006,
  270. ae_EditGraphic        = 3007,
  271. ae_EndTransaction    = 3008,
  272. ae_ImageGraphic        = 3009,
  273. ae_IsUniform        = 3010,
  274. ae_MakeObjVisible    = 3011,
  275. ae_Paste            = 3012,
  276. ae_Redo                = 3013,
  277. ae_Revert            = 3014,
  278. ae_TransactionTerm    = 3015,
  279. ae_Undo                = 3016,
  280. ae_Select            = 3017
  281. };
  282.  
  283.  
  284. //static
  285. /*CALLBACKFORM*/ 
  286. short DApplication::HandleSpecialEvent( long inEvent, long outReply, long inNumber)
  287. {
  288. #ifdef WIN_MAC
  289.     AppleEvent    * inAppleEvent, * outAEReply;
  290.     inAppleEvent= (AppleEvent*) inEvent;
  291.     outAEReply  = (AppleEvent*) outReply;
  292. #endif
  293.     
  294.     switch (inNumber) {
  295.     
  296.         case ae_OpenApp:
  297.             //StartUp();
  298.             break;
  299.             
  300.         case ae_Quit:
  301.             gApplication->Quit();
  302.             break;
  303.  
  304.         case ae_ApplicationDied:
  305.             (void) DChildAppManager::BuryDeadChildApp( inEvent);
  306.             break;
  307.             
  308.         case ae_Copy:
  309.         case ae_Cut:
  310.         case ae_Paste:
  311.         case ae_Redo:
  312.         case ae_Undo:
  313.         case ae_OpenDoc:
  314.         case ae_PrintDoc:
  315.         default:
  316.             //DSomeone::HandleAppleEvent( inAppleEvent, outAEReply, outResult, inNumber);
  317.             break;
  318.         }
  319.  
  320.     return 0;
  321. }
  322.  
  323.  
  324. #ifdef WIN_MAC
  325.  
  326. /*CALLBACKFORM*/
  327. static /* ?? */
  328. short HandleSpecialEvent( long inEvent, long outReply, long inNumber)
  329. {
  330. #ifdef NOTNOW_WIN_MAC
  331.     AppleEvent    * inAppleEvent, * outAEReply;
  332.     inAppleEvent= (AppleEvent*) inEvent;
  333.     outAEReply  = (AppleEvent*) outReply;
  334. #endif
  335.     
  336.     switch (inNumber) {
  337.     
  338.         case ae_ApplicationDied:
  339.             (void) DChildAppManager::BuryDeadChildApp( inEvent);
  340.             break;
  341.             
  342.         case ae_Quit:
  343.             gApplication->Quit();
  344.             break;
  345.  
  346.         case ae_OpenApp:
  347.             //StartUp();
  348.             break;
  349.             
  350.         case ae_Copy:
  351.         case ae_Cut:
  352.         case ae_Paste:
  353.         case ae_Redo:
  354.         case ae_Undo:
  355.         case ae_OpenDoc:
  356.         case ae_PrintDoc:
  357.         default:
  358.             //DSomeone::HandleAppleEvent( inAppleEvent, outAEReply, outResult, inNumber);
  359.             break;
  360.         }
  361.  
  362.     return 0;
  363. }
  364.  
  365. CALLBACKFORM short HandleChildDiedEvent( long inEvent, long outReply, long inNumber)
  366. {
  367.     return ::HandleSpecialEvent( inEvent, outReply, ae_ApplicationDied);
  368. }
  369.  
  370. #endif
  371.  
  372.  
  373. #ifdef WIN_MOTIF
  374. static /*??*/ 
  375. void HandleChildDiedEvent(int signo)
  376. {
  377.     long     pid;
  378.     int        status;
  379.     //pid= wait( &status);
  380.     do {
  381.          pid= waitpid(-1, &status, WNOHANG|WUNTRACED);
  382.          // note: if child exits w/ error, exit(!0), pid == -1 !
  383.         if (pid>0) DApplication::HandleSpecialEvent( pid, 0, ae_ApplicationDied); 
  384.     } while (pid>0);
  385. }
  386. #endif
  387.  
  388.  
  389.  
  390. void DApplication::InitSpecialEvents()
  391. {
  392.     short err;
  393. #ifdef WIN_MAC
  394.  
  395.     // problems w/ "aevt-oapp" call bombing on 68k mac but not ppc mac
  396.     
  397. #define aeproccall(x) NewAEEventHandlerProc(x)
  398. //#define aeproccall(x) ((AEEventHandlerUPP)(x))
  399.  
  400.     err= ::AEInstallEventHandler( kCoreEventClass, kAEOpenApplication,
  401.                                 aeproccall(::HandleSpecialEvent), 
  402.                                 //aeproccall(DApplication::HandleSpecialEvent), 
  403.                                 ae_OpenApp, false);
  404.     err= ::AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, 
  405.                                 aeproccall(::HandleSpecialEvent), 
  406.                                 //aeproccall(DApplication::HandleSpecialEvent), 
  407.                                 ae_Quit, false);
  408.  
  409.     err= ::AEInstallEventHandler( kCoreEventClass, kAEApplicationDied, 
  410.                                 aeproccall(::HandleChildDiedEvent), 
  411.                                 //aeproccall(DApplication::HandleSpecialEvent), 
  412.                                 ae_ApplicationDied, false);
  413.                                 
  414.     err = ::AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
  415.                                 aeproccall(::HandleSpecialEvent), 
  416.                                 //aeproccall(DApplication::HandleSpecialEvent), 
  417.                                 ae_Open, false);
  418.     err = ::AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
  419.                                 aeproccall(::HandleSpecialEvent), 
  420.                                 //aeproccall(DApplication::HandleSpecialEvent), 
  421.                                 ae_Print, false);
  422.  
  423. #endif
  424.  
  425. #ifdef WIN_MOTIF
  426.     // install signals to trap ?? childDied events at least
  427.     //err= sighold( SIGCHLD);
  428. #ifndef OS_UNIX_IRIX
  429.         // need to figure out IRIX format for this
  430.      signal( SIGCHLD, HandleChildDiedEvent); 
  431. #endif
  432. #endif
  433. }
  434.  
  435.  
  436.  
  437. Boolean DApplication::InstallDefaultPrefs(const char* defaultSuffix, const char* appName)
  438. {
  439.     Boolean didinstall= false;
  440.     char  *cp, defaultPrefs[512];
  441.     
  442.         // locate any program default preference file
  443.     if (!appName) appName= Shortname();
  444. #if 0
  445.     const char* appPath = gFileManager->GetProgramPath();  
  446.     appPath= gFileManager->PathOnlyFromPath( appPath);
  447.     StrNCpy(defaultPrefs, (char*)appPath, 512);
  448.     StrNCat(defaultPrefs, (char*)appName, 512);
  449. #else
  450.     StrNCpy(defaultPrefs, (char*)appName, 512);
  451. #endif
  452.     cp= (char*)gFileManager->FileSuffix(defaultPrefs); if (cp) *cp= 0;
  453.     
  454.     StrNCat(defaultPrefs, (char*)defaultSuffix, 512);
  455.  
  456.     if (gFileManager->FileExists(defaultPrefs)) {
  457.         short     iline, nlines = 0;
  458.         char    **linelist;
  459.         char    * cp, * line = NULL, * section = NULL, * varname = NULL, * params = NULL;
  460.         long         curver= 0, defver= 0;
  461.          
  462.         curver= this->GetPrefVal("version","general",NULL);
  463.         linelist= gPrefManager->GetPrefFileLines( defaultPrefs, nlines);
  464.  
  465.             // 1st check quickly if defaultPrefs has anything newer than user prefs
  466.             // if not, exit silently, else put up notice window....
  467.         for (iline= 0; iline<nlines; iline++) {
  468.             line= linelist[iline];
  469.             if (*line == '[') { // sect name 
  470.                 cp= StrStr(line,"[version=");
  471.                 if (cp) defver= atol(cp+9);
  472.                 if (defver > curver) break;
  473.                 }
  474.             }
  475.         if (defver <= curver) return false;    
  476.     
  477.         Nlm_MonitorPtr progress= Nlm_MonitorIntNew("Installing new preferences...", 0, nlines);
  478.                 // ^^^ incorporate Nlm_Monitor into a DCLAP class
  479.         
  480.         gCursor->watch();
  481.         for (iline= 0; iline<nlines; iline++) {
  482.             if (Nlm_MonitorIntValue(progress, iline)) ;
  483.             line= linelist[iline];
  484.             if (line) {
  485.                 if (*line == '[') { // sect name 
  486.                     cp= StrStr(line,"[version=");
  487.                     if (cp)  
  488.                         defver= atol(cp+9);
  489.                     else {
  490.                         if (section) MemFree(section);
  491.                         section= StrDup(line+1);
  492.                         }
  493.                     }
  494.                 else {
  495.                     params= StrChr(line, '=');
  496.                     if (params) *params++= 0;
  497.                     varname= line;
  498.                     if (defver > curver) {
  499.                         this->SetPref( params, varname, section);
  500.                         }
  501.                     }
  502.                 MemFree(line);
  503.                 }
  504.             }
  505.         MemFree(linelist);
  506.         this->SetPref(defver, "version","general");
  507.         didinstall= true;
  508.  
  509.         Nlm_MonitorFree(progress);        
  510.         }
  511.      return didinstall;
  512. }
  513.  
  514.  
  515.  
  516.  
  517. char*    DApplication::GetPref(char* type, char* section, char* defaultvalue)
  518. {
  519.     return gPrefManager->GetAppPref( type, section, (char*)Shortname(), defaultvalue);
  520. }
  521.  
  522. long    DApplication::GetPrefVal(char* type, char* section, char* defaultvalue)
  523. {
  524.     long val= 0;
  525.     char* sval= gPrefManager->GetAppPref( type, section, (char*)Shortname(), defaultvalue);
  526.     if (sval) {
  527.         val= atol(sval);
  528.         MemFree(sval);
  529.         }
  530.     return val;
  531. }
  532.  
  533. char*    DApplication::GetPrefSection(char* section, ulong& sectlen, char* defaultvalue)
  534. {
  535.     return gPrefManager->GetAppPrefSection(section, sectlen, (char*)Shortname(), defaultvalue);
  536. }
  537.  
  538.  
  539. Boolean DApplication::SetPref(char* prefvalue, char* type, char* section)
  540. {
  541.     return gPrefManager->SetAppPref(prefvalue, type, section, (char*)Shortname());
  542. }
  543.  
  544. Boolean DApplication::SetPref(long prefvalue, char* type, char* section)
  545. {
  546.     char    snum[256];
  547.     sprintf(snum, "%d", prefvalue);
  548.     return gPrefManager->SetAppPref(snum, type, section, (char*)Shortname());
  549. }
  550.  
  551. char*    DApplication::ConvertStdFilePath(char* pathname)
  552. {
  553.     char     *path, *name, *newpath;
  554.     
  555.     pathname= StrDup( pathname);
  556.     path= StrChr(pathname, ':');
  557.     if (path) {
  558.         name= path+1;
  559.         *path=0;
  560.         path= this->GetPref( pathname, "paths", NULL);
  561.         if (path) {
  562.             DFileManager::UnixToLocalPath(path);
  563.             newpath= StrDup( DFileManager::BuildPath( path, NULL, name)); 
  564.             MemFree( pathname);
  565.             MemFree( path);
  566.             pathname= newpath;
  567.             }
  568.         else
  569.             ; // return full pathname !?
  570.             // MemMove(pathname, name, StrLen(name)+1);
  571.         }
  572.     return pathname;
  573. }
  574.  
  575. char*    DApplication::GetFilePref(char* type, char* section, char* defaultvalue)
  576. {
  577.     char * pathname, *newpath;
  578.  
  579.     pathname = this->GetPref( type, section, defaultvalue);
  580.     newpath = ConvertStdFilePath( pathname);
  581.     MemFree( pathname);
  582.     return newpath;
  583. }
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590. #ifdef WIN_MOTIF
  591. extern void TaskCentralIdleEvent()
  592. {
  593.     gTaskCentral->NextTask();
  594. }
  595. #endif
  596.  
  597. void    DApplication::Run(void)
  598. {
  599.     if (fAppWindow)  fAppWindow->Open();
  600.     if (gClipboardMgr) gClipboardMgr->Launch();     
  601.  
  602.     gCursor->arrow();  
  603. #ifdef WIN_MOTIF
  604.   Nlm_Metronome( TaskCentralIdleEvent);
  605. #endif
  606.     this->MainEventLoop();
  607.     gCursor->arrow();
  608. }
  609.  
  610. void DApplication::MainEventLoop(void)
  611. {
  612.     while (!fDone) this->ProcessTasks();
  613. }
  614.  
  615. void DApplication::ProcessTasks(void)
  616. {
  617.     Nlm_ProcessEventOrIdle();
  618.     Nlm_RemoveDyingWindows();
  619.     gTaskCentral->NextTask();
  620. }
  621.  
  622. Boolean    DApplication::EventsAvail() 
  623.     return Nlm_EventAvail();
  624. }
  625.  
  626. void    DApplication::FlushEvents() 
  627.     Nlm_FlushEvents();
  628. }
  629.  
  630.  
  631. void DApplication::Quit()
  632. {
  633.     fDone= true;
  634.     if (gWindowManager) delete gWindowManager; gWindowManager= NULL;
  635.     // ?? ^^ is this okay, we got one bomb on a DWindow call after Quit & WinMgr == NULL
  636.     //if (gWindowManager) gWindowManager->suicide();  
  637.   Nlm_QuitProgram (); // this justs sets a local vibrant global, in ProcessEvents(), which we don't see
  638. }
  639.  
  640. void    DApplication::SetAppMenuWindow(DWindow* itsWindow)
  641. {
  642.     fAppWindow= itsWindow;
  643. }
  644.  
  645.  
  646. void    DApplication::OpenDocument(char* pathname)
  647. {
  648.     DFile *afile= new DFile( pathname, "r");
  649.     OpenDocument( afile);
  650.     delete afile; // ???
  651. }
  652.  
  653. void    DApplication::OpenDocument(DFile* aFile)
  654. {
  655.     // default OpenDoc is to use Vibrant's text display
  656.     if (aFile && aFile->Exists()) {
  657.         Nlm_ParData  paratabs = {false, false, false, false, true, 0, 0}; // tabs==tabs
  658.         Nlm_ColData* coldata= NULL;
  659.  
  660.         gCursor->watch();
  661.         aFile->CloseFile(); // ShowFile manages this..
  662.         char* shortname= (char*)aFile->GetShortname();
  663.         DWindow* win= new DWindow(0, this, DWindow::document, -1, -1, -10, -10, shortname);
  664.         DTextDocPanel* td= new DTextDocPanel(0, win, 500, 300);
  665.  
  666.         td->SetSlateBorder( false);
  667.         td->SetResize( DView::matchsuper, DView::relsuper);
  668.         //td->SetTabs( gTextTabStops);
  669.         
  670.         const char* fullname= aFile->GetName();
  671. #if 0
  672.         td->ShowFile( (char*)fullname, gTextFont);
  673. #else
  674.         td->ShowFileFancy( (char*)fullname, ¶tabs, coldata, gTextFont, gTextTabStops);
  675. #endif
  676.         
  677.         win->Open();
  678.         td->SizeToSuperview( win, true, false); // this needs to adjust for if view has scrollbar !
  679.         gCursor->arrow();
  680.         }
  681. }
  682.  
  683.  
  684. Boolean    DApplication::ChooseFile(DFile*& openedFile, char* filesuffix, char* acceptableTypeIDs)
  685. {
  686.     DFile* aFile;
  687.     //if (openedFile) delete openedFile; //??
  688.     openedFile= NULL;
  689.     char* name= (char*) gFileManager->GetInputFileName( filesuffix, acceptableTypeIDs); 
  690.     if (name) {
  691.         aFile= new DFile( name, "r");
  692.         if (aFile->Exists()) {
  693.             openedFile= aFile;
  694.             return true;
  695.             }
  696.         else {
  697.             delete aFile;
  698.             return false;
  699.             }
  700.         }
  701.     else
  702.         return false;
  703. }
  704.  
  705.  
  706.  
  707. Boolean DApplication::DoMenuTask(long tasknum, DTask* theTask)
  708. {
  709.     DWindow* win;
  710.     
  711.     switch (tasknum) {
  712.  
  713.         case DAppleMenu::kAboutMenuItem: 
  714.             // ^^this is likely handled by DAppleMenu object
  715.         case kAbout:
  716.             this->DoAboutBox();
  717.             return true;
  718.  
  719.         case kHelp:
  720.             this->DoHelp();
  721.             return true;
  722.             
  723.         case kNew:
  724.             Message(MSG_OK,"DApplication::New not ready.");
  725.             //this->CreateDocument();
  726.             return true;
  727.             
  728.         case kOpen:
  729.             {
  730.             DFile* aFile = NULL;
  731.             if (this->ChooseFile( aFile, fFileSuffix, fAcceptableFileTypes)) 
  732.                 this->OpenDocument( aFile);
  733.             }
  734.             return true;
  735.             
  736.         case kClose: 
  737.             win= gWindowManager->CurrentWindow();
  738.             if (win) win->CloseAndFree(); // test win for doc needing saving ??
  739.             return true;
  740.                             
  741.         case kSave:
  742.         case kSaveAs:
  743.             win= gWindowManager->CurrentWindow();
  744.             if (win && win->fSaveHandler) {
  745.                 const char* name;
  746.                 char  namestore[256];
  747.                 Boolean changewinname= false;
  748.                 char* defname= win->GetTitle(namestore,sizeof(namestore));
  749.                 if (!defname || !*defname || StrCmp(defname,DFileManager::kUntitled)==0) 
  750.                     tasknum= kSaveAs;  
  751.                 if (tasknum == kSave)
  752.                     name= defname;
  753.                 else {
  754.                     name= gFileManager->GetOutputFileName(defname);
  755.                     changewinname= true;
  756.                     }
  757.                 if (name && *name) {
  758.                     DFile* myFile = new DFile(name, "w");
  759.                     if (myFile) {
  760.                         myFile->OpenFile();
  761.                         win->SaveDoc(myFile); 
  762.                         myFile->CloseFile();
  763.                         delete myFile;
  764.                         if (changewinname) 
  765.                           win->SetTitle((char*)DFileManager::FilenameFromPath(name));
  766.                         }
  767.                     }
  768.                 }
  769.             else 
  770.                 Message(MSG_OK,"DApplication::Save not ready.");
  771.             return true;
  772.  
  773.         case kFindAgain:
  774.             win= gWindowManager->CurrentWindow();
  775.             if (win && win->fFindDlog) 
  776.                 win->fFindDlog->FindAgain(); 
  777.             else
  778.                 Message(MSG_OK,"DApplication::FindAgain not available.");
  779.             return true;
  780.             
  781.         case kFind:
  782.             win= gWindowManager->CurrentWindow();
  783.             if (win && win->fFindDlog) {
  784.                 if ( win->fFindDlog->PoseModally() ) ;
  785.                 }
  786.             else
  787.                 Message(MSG_OK,"DApplication::Find not available.");
  788.             return true;
  789.             
  790.         case kPrint:
  791.             win= gWindowManager->CurrentWindow();
  792.             if (win && win->fPrintHandler) 
  793.                 win->PrintDoc();
  794.             else
  795.                 Message(MSG_OK,"DApplication::Print not ready.");
  796.             return true;
  797.  
  798.         case kQuit:
  799.             this->Quit(); // this should be a task added to end of task queue...??
  800.             return true;
  801.             
  802.         case kPrevWindow:
  803.             gWindowManager->BringToFront();
  804.             return true;
  805.         case kNextWindow:
  806.             gWindowManager->SendToBack();
  807.             return true;
  808.             
  809.         case kChooseWindow:
  810. #ifndef BOBS_WIN_MAC                        
  811.           {
  812.             DWindowChoiceDialog* dlg= new DWindowChoiceDialog();
  813.             if ( dlg->PoseModally() ) {
  814.                 DWindow* win = dlg->Result();
  815.                 if (win && win != dlg) win->Select();
  816.                 }
  817.             delete dlg;
  818.             }
  819. #else
  820. #endif
  821.             return true;
  822.  
  823.         case kUndo:
  824.             if (gLastCommand) gLastCommand->UndoRedo();
  825.             return true;
  826.  
  827.         case kDeleteDeadWindow:
  828.             {
  829.             DView* windowCarcass= (DView*) theTask->fExtra;
  830.             if (windowCarcass) delete windowCarcass;
  831.             }
  832.             return true;
  833.  
  834.         default: 
  835.             return DTaskMaster::DoMenuTask(tasknum, theTask);
  836.         }
  837. }
  838.  
  839.  
  840.  
  841. Boolean DApplication::IsMyAction(DTaskMaster* action)
  842. {
  843.     switch(action->Id()) {
  844.  
  845.         case DAppleMenu::kAboutMenuItem:
  846.         case kAbout:
  847.         case kHelp:
  848.         case kNew:
  849.         case kOpen:
  850.         case kClose:
  851.         case kSaveAs:
  852.         case kSave:
  853.         case kPrint:
  854.         case kQuit:
  855.         case kPrevWindow:
  856.         case kNextWindow:
  857.         case kChooseWindow:
  858.         case kFind:
  859.         case kFindAgain:
  860.         case kUndo:
  861.             return DoMenuTask(action->Id(), NULL);
  862.  
  863.         case kCut:
  864.         case kCopy:
  865.         case kPaste:
  866.         case kClear:
  867.         case kSelectAll:
  868.             {
  869.                     // looks like Vibrant doesn't currently support a system clipboard for
  870.                     // copy/paste of text (& other objects) between applications...
  871.             DWindow* win = gWindowManager->CurrentWindow();
  872.             DDialogText* dtext= gWindowManager->CurrentDialogText();
  873.             if (dtext && win && win->HasEditText()) {
  874.                 if (win != dtext->GetWindow()) dtext = win->fEditText;
  875.                     // ^^ if this is true, we can't tell which of multiple texts may be
  876.                     // the intended target ... CurrentDialogText() is supposed to track user text.
  877.                 if (dtext->IsMyAction(action)) return true;
  878.                 }
  879.             if (win && win->IsMyAction(action)) return true;
  880.             Message(MSG_OK,"Application::Edits not ready.");
  881.             return true;
  882.             }
  883.             
  884.         case kShowClipboard:
  885.             gClipboardMgr->DoMenuTask( action->Id(), NULL);
  886.             return true;
  887.             
  888.         case cOKAY:
  889.         case cCANC:
  890.             {
  891.             DButton* but= (DButton*) action;
  892.             DWindow* win;
  893.             if ( but && ((win= but->GetWindow()) != NULL) ) {
  894.                 if (action->Id() == cOKAY) {
  895.                     // do Okay close handling...
  896.                     }
  897.                 win->CloseAndFree();
  898.                 }
  899.             }
  900.             return true;
  901.  
  902.         default:
  903.             return DTaskMaster::IsMyAction(action);
  904.         }
  905. }
  906.  
  907. DMenu* DApplication::NewMenu(long id, char* title)
  908. {
  909.     Nlm_WindoW nwind = (fAppWindow) ? (Nlm_WindoW)fAppWindow->GetNlmObject() : NULL;
  910.     return new DPulldownMenu( id, this, nwind, title);
  911. }
  912.  
  913.  
  914.  
  915. void    DApplication::SetUpMenus(void)
  916. {
  917.     DMenu* aMenu = NULL;
  918.     this->SetUpMenu(cFileMenu, aMenu);
  919.     aMenu= NULL;
  920.     this->SetUpMenu(cEditMenu, aMenu);
  921.     aMenu= NULL;
  922.     this->SetUpMenu(cWindowMenu, aMenu);
  923. }
  924.  
  925. void DApplication::SetUpMenu(short menuId, DMenu*& aMenu) 
  926. {
  927.     // ?? either change menu objects to local/nonpointer, 
  928.     // or suicide() them to remove all but DViewCentral owner
  929.     
  930.     if (menuId == cFileMenu) {
  931. #ifdef WIN_MAC
  932.         DAppleMenu* appleMenu = new DAppleMenu(this,fAboutLine);
  933. #endif
  934.         if (!aMenu) aMenu = this->NewMenu( cFileMenu, "File");
  935. #ifndef WIN_MAC
  936.         aMenu->AddItem(kAbout, fAboutLine);
  937.         aMenu->AddSeparator();
  938. #endif
  939.         aMenu->AddItem(kNew,"New/N",false, true);
  940.         aMenu->AddItem(kOpen,"Open/O",false, true);
  941.         aMenu->AddSeparator();
  942.         aMenu->AddItem(kClose,"Close/W",false, true);
  943.         aMenu->AddItem(kSave,"Save/S",false, true);
  944.         aMenu->AddItem(kSaveAs,"Save As...",false, true);
  945.         aMenu->AddSeparator();
  946.         aMenu->AddItem(kPrint,"Print",false, true);
  947.         aMenu->AddItem(kHelp,"Help/H",false, true);
  948.         aMenu->AddSeparator();
  949.         aMenu->AddItem(kQuit,"Quit/Q",false, true);
  950.         }
  951.     
  952.     else if (menuId == cEditMenu) {
  953.         if (!aMenu) aMenu = this->NewMenu(cEditMenu, "Edit");
  954.         aMenu->AddItem(kUndo,"Undo/Z",false, true);
  955.         gViewCentral->DisableView(kUndo);  // don't know undo yet... :-(ouch)
  956.         aMenu->AddSeparator();
  957.         aMenu->AddItem(kCut,"Cut/X",false, true);
  958.         aMenu->AddItem(kCopy,"Copy/C",false, true);
  959.         aMenu->AddItem(kPaste,"Paste/V",false, true);
  960.         aMenu->AddItem(kClear,"Clear",false, true);
  961.         aMenu->AddItem(kSelectAll,"Select All/A",false, true);    
  962.         aMenu->AddItem(kShowClipboard,"Show clipboard",false, true);
  963.         gViewCentral->DisableView(DApplication::kShowClipboard);
  964.         }
  965.         
  966.     else if (menuId == cWindowMenu) {
  967.         if (!aMenu) aMenu= this->NewMenu(cWindowMenu, "Windows");
  968.         aMenu->AddItem(kPrevWindow,"Prev/-",false, true); // == bring last win to front
  969.         aMenu->AddItem(kNextWindow,"Next/+",false, true); // == send top win to last
  970.         aMenu->AddItem(kChooseWindow,"Select...");  
  971.         //aMenu->AddSeparator();
  972.         //this->AddWindowListToMenu(menuId, aMenu); //gWindowManager->GetWindowList();
  973.         }
  974.  
  975. }
  976.  
  977.  
  978.  
  979. #if NOT_READY
  980.     
  981. void DApplication::SetWindowMenu(Boolean activate)
  982. {                  
  983. #ifndef BOBS_WIN_MAC                        
  984.                         // THIS IS NO GOOD ON XWIN, and on MSWIN
  985.                         // Vibrant currently has no way of removing single menu items
  986.                         // except for Mac.  Only option for others seems to be removal
  987.                         // of entire (sub) menu, with no way to replace w/ a new menu
  988.                         // in *same* position !!!
  989. #else                        
  990.    if (fWindowChoiceMenu) {
  991.          short item= kViewDefault;
  992.          fWindowChoiceMenu->Reset();  
  993.          fWindowChoiceMenu->AddItem( item, "default");
  994.          DList* wins= gWindowManager->GetWindowList();
  995.          if (activate && wins) {
  996.             long i, n= wins->GetSize();
  997.             for (i= 0; i<n; i++) {
  998.                 char *cp, title[256];
  999.                 item++;
  1000.                 DWindow* win= (DWindow*) fList->At(i);
  1001.                 win->GetTitle(title,256);
  1002.                 cp= title; 
  1003.                 //while (cp= strchr(cp, '/')) *cp= '_';
  1004.                 fViewChoiceMenu->AddItem( item, smenu);
  1005.                 }
  1006.              }
  1007.      }
  1008. #endif
  1009. }
  1010.  
  1011. #endif
  1012.  
  1013.  
  1014.  
  1015.      
  1016. void DApplication::DoHelp()
  1017. {
  1018.     char filename[512];
  1019.     DFile* afile = new DFile();
  1020.     char* suf;
  1021.     
  1022.     char* apppath = (char*) gFileManager->GetProgramPath();  
  1023.     apppath= (char*) gFileManager->PathOnlyFromPath( apppath);
  1024.     apppath= (char*)gFileManager->BuildPath( apppath, kHelpfolder, (char*)Shortname());
  1025.     afile->Initialize(apppath,"r");
  1026.     if (!afile->Exists()) {
  1027.         StrNCpy(filename, (char*)Shortname(),490);
  1028.         StrCat(filename,".help");
  1029.         afile->Initialize(filename,"r");
  1030.         if (!afile->Exists()) {
  1031.             StrNCpy(filename, (char*)Pathname(),490);
  1032.             suf= (char*)gFileManager->FileSuffix(filename); if (suf) *suf= 0;
  1033.             StrCat(filename,".help");
  1034.             afile->Initialize(filename,"r");
  1035.             }
  1036.         }
  1037.     OpenHelp( afile);
  1038.     delete afile;
  1039. }
  1040.  
  1041.  
  1042.  
  1043. void DApplication::OpenHelp(const char* helpname)
  1044. {
  1045.     char* apppath = (char*) gFileManager->GetProgramPath();  
  1046.     apppath= (char*) gFileManager->PathOnlyFromPath( apppath);
  1047.     const char*    pathname= gFileManager->BuildPath( apppath, kHelpfolder, helpname);
  1048.     DFile* afile = new DFile(pathname,"r");
  1049.     OpenHelp(afile);
  1050.     delete afile;
  1051. }
  1052.  
  1053.  
  1054. void DApplication::OpenHelp(DFile* aFile)
  1055. {
  1056. #if 1
  1057.     if (!aFile || !aFile->Exists()) {
  1058.         const char * name;
  1059.         if (aFile) name= aFile->GetName(); else name= "noname";
  1060.         Message(MSG_OK,"Can't find help file '%s'",name);
  1061.         return;
  1062.         }
  1063.     this->OpenDocument( aFile); 
  1064. #else
  1065.     Nlm_ParData  paratabs = {false, false, false, false, true, 0, 0}; // tabs==tabs
  1066.     Nlm_ColData* coldata= NULL;
  1067.         
  1068.     if (!aFile->Exists()) {
  1069.         Message(MSG_OK,"Can't find help file '%s'",aFile->GetName());
  1070.         return;
  1071.         }
  1072.         
  1073.     gCursor->watch();
  1074.     aFile->CloseFile(); // make sure closed so ShowFile can open !?
  1075.     DWindow* win= new DWindow(cHelp, this, DWindow::document, -1, -1, -10, -10, 
  1076.                                         (char*) aFile->GetShortname());
  1077.     DTextDocPanel* td= new DTextDocPanel(0, win, 490, 300);
  1078.     td->SetSlateBorder( false);
  1079.     td->SetResize( DView::matchsuper, DView::relsuper);
  1080. #if 0
  1081.     td->ShowFile( (char*)aFile->GetName(), gTextFont);
  1082. #else
  1083.     td->ShowFileFancy( (char*)aFile->GetName(), ¶tabs, coldata, gTextFont, gTextTabStops);
  1084. #endif
  1085.     win->Open();
  1086.     td->SizeToSuperview( win, true, false);  
  1087.     gCursor->arrow();
  1088. #endif
  1089. }
  1090.  
  1091.  
  1092. void DApplication::DoAboutBox(void)
  1093. {
  1094.     DAboutBoxWindow* about = new DAboutBoxWindow; // make instance & it handles rest
  1095. }
  1096.  
  1097.     
  1098.  
  1099.  
  1100. void DApplication::UpdateMenus( void)
  1101. {
  1102.         // Is the frontmost window modal?
  1103.     
  1104.     gViewCentral->EnableView(DApplication::kQuit);
  1105.  
  1106.     //if (gInBackground) 
  1107.     {
  1108.         gViewCentral->EnableView(DApplication::kClose);
  1109.         //gViewCentral->EnableView(DApplication::kUndo);
  1110.         gViewCentral->EnableView(DApplication::kCut);
  1111.         gViewCentral->EnableView(DApplication::kCopy);
  1112.         gViewCentral->EnableView(DApplication::kPaste);
  1113.         gViewCentral->EnableView(DApplication::kClear);
  1114.     } 
  1115.  
  1116.     //if (!isModalWindow) 
  1117.     {
  1118.         gViewCentral->EnableView(DApplication::kNew);
  1119.         gViewCentral->EnableView(DApplication::kOpen);
  1120.     }
  1121.  
  1122.     gViewCentral->EnableView(DApplication::kPrevWindow);
  1123.     gViewCentral->EnableView(DApplication::kNextWindow);
  1124.     
  1125.     //Str63    undoStr;
  1126.     //GetIndString(undoStr, STRcommon, strUNDO);
  1127.     //gViewCentral->SetMenuText( DApplication::kUndo, undoStr);
  1128. }
  1129.  
  1130.  
  1131.  
  1132.  
  1133.